package de.htwsaar.smog.datagenerator;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;

public class RandomSensorDataPopulator {

	private static final int PARTICLES_MAX = 42;

	private final DBCollection collection;

	private final Random random = new Random();

	private final GregorianCalendar calendar = new GregorianCalendar();

	private final Locale locale = new Locale("en", "UK");
	private final String pattern = "####.000000";
	private final DecimalFormat locFormat = (DecimalFormat) NumberFormat.getNumberInstance(locale);

	
	public RandomSensorDataPopulator(DBCollection c) {
		this.collection = c;
		
		
		locFormat.applyPattern(pattern);
	}

	public void populate(int sensorsAmount, int packagesPerSensor) {

		// Wir lassen 'sensorsAmount' Koordinatenpaare erzeugen. Kollisionen
		// sind uns egal.
		Map<String, String> coordinates = makeCoordinates(sensorsAmount);
		System.out.println("Generated " + sensorsAmount + " coordinate pairs");

		for (String key : coordinates.keySet()) {

			System.out.println("Generating data for " + key + ", " + coordinates.get(key));

			// Und für jedes dieser Paare gibts jetzt 'packagesPerSensor'
			// Inserts
			for (int i = 0; i < packagesPerSensor; i++) {

				DBObject o = buildObject(key, coordinates.get(key));
				collection.insert(o);
			}
		}

		System.out.println("Inserted " + sensorsAmount * packagesPerSensor + " documents");

	}

	private DBObject buildObject(String lat, String lon) {

		// TODO: gucken wie das geht
		BasicDBObjectBuilder builder = new BasicDBObjectBuilder();

		builder.add("sensor_id", lon + lat);
		builder.add("location", "Shanghai");
		builder.add("longitude", lon);
		builder.add("latitude", lat);
		builder.add("type", "pm10");
		builder.add("value", random.nextInt(PARTICLES_MAX));
		builder.add("time", makeRandomDate());

		return builder.get();
	}

	private Date makeRandomDate() {

		calendar.clear();

		// 2014, Uhrzeit, Tag egal.
		int month = 11; // alles im Dezember :-)
		int day = random.nextInt(29) + 1;
		int hour = random.nextInt(23);
		int minute = random.nextInt(55);

		calendar.set(2014, month, day, hour, minute);

		return calendar.getTime();
	}

	private Map<String, String> makeCoordinates(int n) {

		// Saarbrücken
//		 final double minlon = 6.940000;
//		 final double maxlon = 7.070000;
//		 final double minlat = 49.220000;
//		 final double maxlat = 49.260000;

		// Shanghai
		final double minlon = 120.800000;
		final double maxlon = 121.800000;
		final double minlat = 30.900000;
		final double maxlat = 31.600000;

		Map<String, String> coordinates = new HashMap<String, String>();

		// n Koordinatenpaare erzeugen, jedes Paar repräsentiert einen Sensor
		for (int i = 0; i < n; i++) {

			double dlon = minlon + (maxlon - minlon) * random.nextDouble();
			double dlat = minlat + (maxlat - minlat) * random.nextDouble();

			String lon = locFormat.format(dlon);
			String lat = locFormat.format(dlat);

			coordinates.put(lat, lon);
		}

		return coordinates;
	}

}
